/*
 * for use to store data that users filled.
 */

package wads.com;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.Properties;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 *
 * @author Nattasan W.
 */
public class WadsXML {
  //Header section
  private Properties WadsHeader = new Properties(); //Have only one
  public static final String WH_REQUESTER = "Requester";
  public static final String WH_CREATED = "Created";
  public static final String WH_DESCRIPTION = "Description";
  
  //RequestDetails section
  private Vector<Vector> RequestDetails = new Vector<Vector>(); //Have only one
  private Vector<String> Archetype = new Vector<String>(); //Have only one, index: [0=Id, 1=Name, 2=Path]
  public static final int ARCH_ID = 0;
  public static final int ARCH_NAME = 1;
  public static final int ARCH_PATH = 2;
  private Vector<String> CurrentActivityId = new Vector<String>(); //Have only one, index: [0=CurrentActivityId]
  private Vector<Properties> DataFields = new Vector<Properties>(); //Have only one
  private Properties DataField; //May have more than one
  public static final String DF_ID = "Id";
  public static final String DF_NAME = "Name";
  public static final String DF_VAL = "Val";
  
  //Approvals section
  private Vector<Properties> Approvals = new Vector<Properties>(); //Have only one
  private Properties Approval; //May have more than one
  public static final String AP_ID = "Id";
  public static final String AP_ACTIVITYID = "ActivityId";
  public static final String AP_APPROVER = "Approver";
  public static final String AP_CREATED = "Created";
  public static final String AP_REPLIED = "Replied";
  public static final String AP_MESSAGE = "Message";
  
  public WadsXML() {
    WadsHeader.setProperty(WH_REQUESTER, "");
    WadsHeader.setProperty(WH_CREATED, "");
    WadsHeader.setProperty(WH_DESCRIPTION, "");
    
    Archetype.add("id");
    Archetype.add("name");
    Archetype.add("path");
    CurrentActivityId.add("currentactivityid");
    
    RequestDetails.add(Archetype);
    RequestDetails.add(CurrentActivityId);
    RequestDetails.add(DataFields);
  }
  
  public void setRequester(String requester) {
    WadsHeader.setProperty(WH_REQUESTER, requester);
  }
  
  public String getRequester() {
    return WadsHeader.getProperty(WH_REQUESTER, "");
  }
  
  public void setWHCreated(String created) {
    WadsHeader.setProperty(WH_CREATED, created);
  }
  
  public String getWHCreated() {
    return WadsHeader.getProperty(WH_CREATED, "");
  }
  
  public void setDescription(String desc) {
    WadsHeader.setProperty(WH_DESCRIPTION, desc);
  }
  
  public String getDescription() {
    return WadsHeader.getProperty(WH_DESCRIPTION, "");
  }
  
  public void setArchetype(int flag, String value) {
    Archetype.set(flag, value);
  }
  
  public void setArchetype(String id, String name, String path) {
    Archetype.set(0, id);
    Archetype.set(1, name);
    Archetype.set(2, path);
  }
  
  public String getArchetype(int flag) {
    return Archetype.get(flag);
  }
  
  public void setCurrentActivityId(String cur) {
    CurrentActivityId.set(0, cur);
  }
  
  public String getCurrentActivityId() {
    return CurrentActivityId.get(0);
  }
  
  public void addDataField(Properties dataf) {
    DataFields.add(dataf);
  }
  
  public Vector<Properties> getDataFiels() {
    return DataFields;
  }
  
  public void createDataField(String id, String name, String val) {
    DataField = new Properties();
    DataField.setProperty(DF_ID, id);
    DataField.setProperty(DF_NAME, name);
    DataField.setProperty(DF_VAL, val);
    
    DataFields.add(DataField);
  }
  
  public void addApproval(Properties app) {
    Approvals.add(app);
  }
  
  public Vector<Properties> getApprovals() {
    return Approvals;
  }
  
  public void createApproval(String id, String activityid, String approver, String created, String replied, String message) {
    Approval = new Properties();
    Approval.setProperty(AP_ID, id);
    Approval.setProperty(AP_ACTIVITYID, activityid);
    Approval.setProperty(AP_APPROVER, approver);
    Approval.setProperty(AP_CREATED, created);
    Approval.setProperty(AP_REPLIED, replied);
    Approval.setProperty(AP_MESSAGE, message);
    
    Approvals.add(Approval);
  }
  
  public static WadsXML fromXML(String path) {
    return fromXML(new File(path));
  }
  
  public static WadsXML fromXML(File file) {
    try {
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      DocumentBuilder loader = factory.newDocumentBuilder();
      Document document = loader.parse(file);
      Element wads = document.getDocumentElement();
      WadsXML wadsxml = new WadsXML();
      
      if(wads.getNodeName().equals("Wads")) {
        for(int i=0;i<wads.getChildNodes().getLength();i++) {
          if(wads.getChildNodes().item(i).getNodeName().equals("WadsHeader")) {
            Node wadsheader = wads.getChildNodes().item(i);
            for(int j=0;j<wadsheader.getChildNodes().getLength();j++) {
              if(wadsheader.getChildNodes().item(j).getNodeName().equals("Requester")) {
                wadsxml.setRequester(wadsheader.getChildNodes().item(j).getTextContent());
                System.out.println("Item found: "+wadsheader.getChildNodes().item(j).getTextContent());
              }
              if(wadsheader.getChildNodes().item(j).getNodeName().equals("Created")) {
                wadsxml.setWHCreated(wadsheader.getChildNodes().item(j).getTextContent());
                System.out.println("Item found: "+wadsheader.getChildNodes().item(j).getTextContent());
              }
              if(wadsheader.getChildNodes().item(j).getNodeName().equals("Description")) {
                wadsxml.setDescription(wadsheader.getChildNodes().item(j).getTextContent());
                System.out.println("Item found: "+wadsheader.getChildNodes().item(j).getTextContent());
              }
            }
          }
          
          if(wads.getChildNodes().item(i).getNodeName().equals("RequestDetails")) {
            Node requestdetails = wads.getChildNodes().item(i);
            for(int k=0;k<requestdetails.getChildNodes().getLength();k++) {
              if(requestdetails.getChildNodes().item(k).getNodeName().equals("Archetype")) {
                Node arch = requestdetails.getChildNodes().item(k);
                for(int a=0;a<arch.getAttributes().getLength();a++) {
                  if(arch.getAttributes().item(a).getNodeName().equals("Id")) {
                    wadsxml.setArchetype(ARCH_ID, arch.getAttributes().item(a).getNodeValue());
                  }
                  if(arch.getAttributes().item(a).getNodeName().equals("Name")) {
                    wadsxml.setArchetype(ARCH_NAME, arch.getAttributes().item(a).getNodeValue());
                  }
                  if(arch.getAttributes().item(a).getNodeName().equals("Path")) {
                    wadsxml.setArchetype(ARCH_PATH, arch.getAttributes().item(a).getNodeValue());
                  }
                }
              }
              if(requestdetails.getChildNodes().item(k).getNodeName().equals("CurrentActivity")) {
                wadsxml.setCurrentActivityId(requestdetails.getChildNodes().item(k).getAttributes().item(0).getNodeValue());
                System.out.println("Item found: "+requestdetails.getChildNodes().item(k).getAttributes().item(0).getNodeValue());
              }
              if(requestdetails.getChildNodes().item(k).getNodeName().equals("DataFields")) {
                Node datafields = requestdetails.getChildNodes().item(k);
                for(int l=0;l<datafields.getChildNodes().getLength();l++) {
                  NodeList dataf = document.getElementsByTagName("DataField");
                  for(int a=0;a<dataf.getLength();a++) {
                    //DataField refDataField = new DataField(refDataFields);
                    for(int b=0;b<dataf.item(a).getAttributes().getLength();b++) {
                      String dfid="", dfname="", dfval="";
                      if(dataf.item(a).getAttributes().item(b).getNodeName().equals("Id")) {
                        dfid = dataf.item(a).getAttributes().item(b).getNodeValue();
                        System.out.println("Item found: "+dataf.item(a).getAttributes().item(b));
                      }
                      if(dataf.item(a).getAttributes().item(b).getNodeName().equals("Name")) {
                        dfname = dataf.item(a).getAttributes().item(b).getNodeValue();
                        System.out.println("Item found: "+dataf.item(a).getAttributes().item(b));
                      }
                      if(dataf.item(a).getAttributes().item(b).getNodeName().equals("Val")) {
                        dfval = dataf.item(a).getAttributes().item(b).getNodeValue();
                        System.out.println("Item found: "+dataf.item(a).getAttributes().item(b).getNodeValue());
                      }
                      wadsxml.createDataField(dfid, dfname, dfval);
                    }
                  }
                }
              }
            }
          }
          
          if(wads.getChildNodes().item(i).getNodeName().equals("Approvals")) {
            NodeList approvallist = document.getElementsByTagName("Approval");
            for(int a=0;a<approvallist.getLength();a++) {
              for(int b=0;b<approvallist.item(a).getChildNodes().getLength();b++) {
                String apid="", apactid="", apappr="", apcre="", aprep="", apmsg="";
                apid = approvallist.item(a).getAttributes().item(0).getNodeValue();
                System.out.println("Item found: "+approvallist.item(a).getAttributes().item(0).getNodeValue());
                if(approvallist.item(a).getChildNodes().item(b).getNodeName().equals("ActivityId")) {
                  apactid = approvallist.item(a).getChildNodes().item(b).getTextContent();
                  System.out.println("Item found: "+approvallist.item(a).getChildNodes().item(b).getTextContent());
                }
                if(approvallist.item(a).getChildNodes().item(b).getNodeName().equals("Approver")) {
                  apappr = approvallist.item(a).getChildNodes().item(b).getTextContent();
                  System.out.println("Item found: "+approvallist.item(a).getChildNodes().item(b).getTextContent());
                }
                if(approvallist.item(a).getChildNodes().item(b).getNodeName().equals("Created")) {
                  apcre = approvallist.item(a).getChildNodes().item(b).getTextContent();
                  System.out.println("Item found: "+approvallist.item(a).getChildNodes().item(b).getTextContent());
                }
                if(approvallist.item(a).getChildNodes().item(b).getNodeName().equals("Replied")) {
                  aprep = approvallist.item(a).getChildNodes().item(b).getTextContent();
                  System.out.println("Item found: "+approvallist.item(a).getChildNodes().item(b).getTextContent());
                }
                if(approvallist.item(a).getChildNodes().item(b).getNodeName().equals("Message")) {
                  apmsg = approvallist.item(a).getChildNodes().item(b).getTextContent();
                  System.out.println("Item found: "+approvallist.item(a).getChildNodes().item(b).getTextContent());
                }
                wadsxml.createApproval(apid, apactid, apappr, apcre, aprep, apmsg);
              }
            }
          }
        }
      }
      return wadsxml;
      
    } catch (SAXException ex) {
      Logger.getLogger(WADSUtil.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
      Logger.getLogger(WADSUtil.class.getName()).log(Level.SEVERE, null, ex);
    } catch (ParserConfigurationException ex) {
      Logger.getLogger(WADSUtil.class.getName()).log(Level.SEVERE, null, ex);
    }
    return null;
  }
  
  public static void toXML(WadsXML wads, File wadsfile) {
    try {
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      DocumentBuilder builder = factory.newDocumentBuilder();
      Document wadsDoc = builder.newDocument();
      
      Element root = wadsDoc.createElement("Wads");
      wadsDoc.appendChild(root);
      
      Element wadsheader = wadsDoc.createElement("WadsHeader");
      root.appendChild(wadsheader);
      Element requestdetails = wadsDoc.createElement("RequestDetails");
      root.appendChild(requestdetails);
      Element approvals = wadsDoc.createElement("Approvals");
      root.appendChild(approvals);
      
      Element requester = wadsDoc.createElement(WH_REQUESTER);
      requester.appendChild(wadsDoc.createTextNode(wads.getRequester()));
      wadsheader.appendChild(requester);
      Element created = wadsDoc.createElement(WH_CREATED);
      created.appendChild(wadsDoc.createTextNode(wads.getWHCreated()));
      wadsheader.appendChild(created);
      Element desc = wadsDoc.createElement(WH_DESCRIPTION);
      desc.appendChild(wadsDoc.createTextNode(wads.getDescription()));
      wadsheader.appendChild(desc);
      
      Element archetype = wadsDoc.createElement("Archetype");
      archetype.setAttribute("Id", wads.getArchetype(ARCH_ID));
      archetype.setAttribute("Name", wads.getArchetype(ARCH_NAME));
      archetype.setAttribute("Path", wads.getArchetype(ARCH_PATH));
      requestdetails.appendChild(archetype);
      
      Element curr = wadsDoc.createElement("CurrentActivityId");
      curr.setAttribute("Id", wads.getCurrentActivityId());
      requestdetails.appendChild(curr);
      
      Element datafields = wadsDoc.createElement("DataFields");
      System.out.println(wads.getDataFiels().size()+"AAAAAA");
      for(int o=0;o<wads.getDataFiels().size();o++) {
        Element datafield = wadsDoc.createElement("DataField");
        datafield.setAttribute(DF_ID, wads.getDataFiels().elementAt(o).getProperty(DF_ID, ""));
        datafield.setAttribute(DF_NAME, wads.getDataFiels().elementAt(o).getProperty(DF_NAME, ""));
        datafield.setAttribute(DF_VAL, wads.getDataFiels().elementAt(o).getProperty(DF_VAL, ""));
        datafields.appendChild(datafield);
      }
      requestdetails.appendChild(datafields);
      
      for(int p=0;p<wads.getApprovals().size();p++) {
        Element approval = wadsDoc.createElement("Approval");
        approval.setAttribute(AP_ID, wads.getApprovals().elementAt(p).getProperty(AP_ID));
        approval.appendChild(wadsDoc.createElement(AP_ACTIVITYID).appendChild(wadsDoc.createTextNode(wads.getApprovals().elementAt(p).getProperty(AP_ACTIVITYID))));
        approval.appendChild(wadsDoc.createElement(AP_APPROVER).appendChild(wadsDoc.createTextNode(wads.getApprovals().elementAt(p).getProperty(AP_APPROVER))));
        approval.appendChild(wadsDoc.createElement(AP_CREATED).appendChild(wadsDoc.createTextNode(wads.getApprovals().elementAt(p).getProperty(AP_CREATED))));
        approval.appendChild(wadsDoc.createElement(AP_REPLIED).appendChild(wadsDoc.createTextNode(wads.getApprovals().elementAt(p).getProperty(AP_REPLIED))));
        approval.appendChild(wadsDoc.createElement(AP_MESSAGE).appendChild(wadsDoc.createTextNode(wads.getApprovals().elementAt(p).getProperty(AP_MESSAGE))));
        approvals.appendChild(approval);
      }
      
      //Write to file
      DOMSource source = new DOMSource(wadsDoc);
      Transformer trans = TransformerFactory.newInstance().newTransformer();
      trans.setOutputProperty("indent", "yes");
      trans.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
      trans.setOutputProperty("encoding", "utf-8");
      StreamResult fresult = new StreamResult(new OutputStreamWriter(new FileOutputStream(wadsfile, false), "UTF-8"));
      trans.transform(source, fresult);
    } catch (UnsupportedEncodingException ex) {
      Logger.getLogger(WADSUtil.class.getName()).log(Level.SEVERE, null, ex);
    } catch (TransformerException ex) {
      Logger.getLogger(WADSUtil.class.getName()).log(Level.SEVERE, null, ex);
    } catch (FileNotFoundException ex) {
      Logger.getLogger(WADSUtil.class.getName()).log(Level.SEVERE, null, ex);
    } catch (ParserConfigurationException ex) {
      Logger.getLogger(WADSUtil.class.getName()).log(Level.SEVERE, null, ex);
    }
  }
}
